#ifndef MAPREADER_H_
#define MAPREADER_H_

#include <string>
#include <stdint.h>
#include <map>
#include "Map.h"
#include "FileInterface.h"
#include "Location.h"
#include "MapTiles.h"
#include "Road.h"
#include "Search.h"
#include "Geo.h"

namespace opennav {

class MapTileDef;

class MapReader {
public:
	MapReader(FileInterface* inputfile, Map* map);
	/*
	 * Location Subfile Section
	 */
public:
	const LocationHeader& location_header() const;
	void location_country_entry(uint8_t country_id, Country& country);
	void location_region_entry(int16_t region_id, Region& region);
	void location_city_entry(int32_t city_id, City& city);
private:
	void read_location_header();
	/*
	 * Map Subfile Section
	 */
public:
	const MapTileHeader& map_tile_header() const;
	void zoom_table_entry(uint8_t level, Zoom& zoom);
	void zoom_table_entries(std::vector<Zoom>& zoom_levels);
	void map_tile_def_table_entry(uint16_t tile_id, MapTileDef& tile_def);
	void map_tile_def_table_entries(std::vector<MapTileDef>& tile_defs);
	void map_tile_table_entry(const MapTileDef& tile_def, std::vector<MapObject*>& tile_content);
private:
	void read_map_tile_header();
	/*
	 * Road Subfile Section
	 */
public:
	const RoadHeader& road_header() const;
	void road_road_entry(int32_t id, Road& road);
	void road_segment_entry(int32_t offset, RoadSegment& segment);
	void road_segment_entries(int32_t offset, std::vector<RoadSegment>& segments);
	void road_junction_entry(int32_t offset, RoadJunction& junction);
private:
	void read_road_header();
	/*
	 * Label Subfile Section
	 */
public:
	std::string load_label(int32_t offset) const;
	/*
	 * Search Subfile Section
	 */
public:
	const SearchHeader& search_header() const;
	void search_sorted_country_table_entry(uint8_t entry_id, SortedCountryTableEntry& entry);
	void search_country_to_city_table_entry(uint8_t entry_id, CountryToCityTableEntry& entry);
	void search_sorted_city_table_entry(int32_t entry_id, SortedCityTableEntry& entry);
	void search_city_to_road_table_entry(int32_t entry_id, CityToRoadTableEntry& entry);
	void search_sorted_road_table_entry(int32_t entry_id, SortedRoadTableEntry& entry);
private:
	void read_search_header();
private:
	FileInterface* inputfile_;
	Map* map_;
	int32_t offset_road_;
	RoadHeader header_road_;
	int32_t offset_search_;
	SearchHeader header_search_;
	int32_t offset_location_;
	LocationHeader header_location_;
	int32_t offset_map_tiles_;
	MapTileHeader header_map_tiles_;
	int32_t offset_label_;
};

}
#endif /* MAPREADER_H_ */
